import sys, os
sys.path.append(os.path.realpath('../../'))
sys.path.append(os.path.realpath('../../server-comm'))

import web
import json
from threading import Thread
import time
import socket, select
from pymongo import MongoClient

from Fingerprint_Module_R1020.util import FingerHelper
import test_broadcast_send

# class WorkQueue(object):
#     """docstring for WorkQueue"""
#     def __init__(self, queue = [], step = 1):
#         super(WorkQueue, self).__init__()
#         self._queue_cluster = {}
#         self._last_time = 0
#         # Cluster init queue
#         for item in queue:
            
#     def insert(message):
#         message_time = message.time
#         message_time = int(message_time / self.step)
#         if message_time == self._last_time:
#             self.queue.append(message)
#         if message_time > self._last_time:
#             self._last_time = message_time
#             self.queue.append(message)
#             self._queue_cluster[str(self._last_time)] = len(self.queue)

#     def get(start_time):
#         start_time_instep = int(start_time / self.step)

# class WorkMessage(object):
#     """docstring for WorkMessage"""
#     def __init__(self, name = "", worker = None, data = None, time = 0):
#         super(WorkMessage, self).__init__()
#         self.name = name
#         self.worker = worker
#         self.data = data
#         self.time = time

class WorkerThread(Thread):
    # def __init__(self,queue,threadname="Worker",init_configs={}):
    def __init__(self,db,threadname="Worker",init_configs={}):
        Thread.__init__(self, name=threadname)
        # self.queue = queue
        self.db = db
        self.threadname = threadname
        self.tinit(init_configs)
        self.isrunning = True
    def tinit(self, init_configs):
        return None
    def run(self):
        return None
    def putMessage(self, data):
        if not data == None: 
            # self.queue.append({
            #     "name": self.threadname,
            #     "worker": self,
            #     "data": data,
            #     "time": time.time()
            # })
            self.db.workermessages.insert({
                "name": self.threadname,
                "data": data,
                "time": time.time()
            })
    def stop(self):
        self.isrunning = False

class WorkerTimer(WorkerThread):
    def tinit(self, init_configs):
        self.interval = init_configs['interval'] or 1
    def run(self):
        while self.isrunning:
            self.putMessage(self.getMessage())
            time.sleep(self.interval)
    def getMessage(self):
        return '[Thread] thread %s is running,time:%s\n' %(self.getName(),time.ctime())

class WorkerRemote(WorkerThread):
    ''' Remote control communication '''
    def tinit(self, init_configs):
        print "Init WorkerRemote"
        host = init_configs['host'] if init_configs.has_key('host') else 'localhost'
        port = init_configs['port'] if init_configs.has_key('port') else 9001
        # self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        # self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
        # self.sock.setblocking(0)
        # self.sock.sendto('w', ('<broadcast>',9001))
        self.bufsize = init_configs['bufsize'] if init_configs.has_key('bufsize') else 1024

        self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        self.sock.bind((host,port))
    def run(self):
        while self.isrunning:
            data,addr=self.sock.recvfrom(self.bufsize)
            print('[Remote] Received:',data,'from',addr)
            # self.putMessage('[Remote] Received: ' + data + ' from ' + addr[0])
            split_data = data.split('-')
            self.putMessage({
                "type": split_data[0],
                "status": split_data[1]
            })

# ===================================================

# def add_global_hook():
#     g = web.storage({"queue": []})
#     def _wrapper(handler):
#         web.ctx.globals = g
#         return handler()
#     return _wrapper
# if __name__ == "__main__":
#     web.ctx.globals = web.storage({"queue": []})
#     print web.ctx.globals.queue

settings = {
    "MONGODB_SERVER": 'localhost',
    "MONGODB_PORT": 27017,
    "MONGODB_DB": 'fingercar'
}

connection = MongoClient(settings['MONGODB_SERVER'], settings['MONGODB_PORT'])
db = connection[settings['MONGODB_DB']]

render = web.template.render('templates/')

urls = (
    '/', 'Index',
    '/api/event', 'ApiEvent',
    '/api/heartbeat', 'ApiHeartbeat',
    '/api/message', 'ApiMessage'
)

class Index:
    def GET(self):
        # return render.index(str(len(web.ctx.globals.queue)))
        return render.index('0')

class ApiEvent:
    def GET(self):
        data = {
            "error": 0,
            "data": None
        }
        return json.dumps(data)
    def POST(self):
        data = json.loads(web.data())
        if data['type'] == "register":
            # eventRegister()
            test_broadcast_send.send('register', port = 9002)

class ApiHeartbeat:
    def GET(self):
        data_data = None
        # queue_len = len(web.ctx.globals.queue)
        # start_idx = web.input(idx=None).idx
        # print start_idx, queue_len
        # if (start_idx != None) and (start_idx.isdigit()) and (int(start_idx) < queue_len):
        #     data_data = {
        #         "next_idx": queue_len,
        #         "msgs": []
        #     }
        #     for msg_item in web.ctx.globals.queue[int(start_idx):]:
        #         data_data['msgs'].append(msg_item['data'])
        last_time = web.input(last_time=None).last_time
        print "last_time: ", last_time
        if (last_time != None) and (last_time.isdigit()):
            last_time = int(last_time)
            queue = db.workermessages.find({"time":{"$gt": float(last_time) / 1000}})
            # if queue.length() > 0:
            #     data_data = {
            #         "last_time": int(queue[-1].time * 1000),
            #         "msgs": []
            #     }
            #     for msg_item in queue:
            #         data_data['msgs'].append(msg_item['data'])
            for item in queue:
                if int(item['time'] * 1000) == last_time: 
                    continue;
                else:
                    print int(item['time'] * 1000), last_time
                if not data_data: 
                    data_data = {
                        "last_time": 0,
                        "msgs": []
                    }
                data_data['last_time'] = item['time']
                data_data['msgs'].append(item['data'])
            if not (data_data == None): data_data['last_time'] = int(data_data['last_time'] * 1000)
            # print len(data_data['msgs']), data_data['last_time']
        data = {
            "error": 0,
            "data": data_data
        }
        return json.dumps(data)

class ApiMessage:
    def GET(self):
        data = {
            "error": 0,
            "data": None
        }
        return json.dumps(data)
    def POST(self):
        rcv_msg = web.data()
        data = {
            "error": 0,
            "data": rcv_msg
        }
        return json.dumps(data)

if __name__ == "__main__":
    # worker_timer = WorkerTimer(db, "timer", {'interval':3})
    # worker_timer.start()
    worker_remote = WorkerRemote(db, "remote", {'host':'', 'port':9001})
    worker_remote.start()
    app = web.application(urls, globals())
    # app.add_processor(add_global_hook())
    app.run()